home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / DevCon / Atlanta_1990 / Atlanta-Devcon.1 / Libraries / Intuition / boopsi / frame1class.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-26  |  7.7 KB  |  339 lines

  1. /* frameclass.c -- :ts=8
  2.  * Example of a PUBLIC image class with FRAME capability.
  3.  *
  4.  * This one does a raised embossed box.
  5.  * Doesn't do resolution sensitive bevel widths yet,
  6.  * nor correctly supports IA_LINEWIDTH yet.
  7.  */
  8.  
  9. /*
  10. Copyright (c) 1989, 1990 Commodore-Amiga, Inc.
  11.  
  12. Executables based on this information may be used in software
  13. for Commodore Amiga computers. All other rights reserved.
  14. This information is provided "as is"; no warranties are made.
  15. All use is at your own risk, and no liability or responsibility
  16. is assumed.
  17. */
  18.  
  19. #include "sysall.h"
  20.  
  21. #if 0    /* in sysall.h    */
  22. #include <intuition/classusr.h>
  23. #include <intuition/classes.h>
  24. #include <intuition/imageclass.h>
  25. #endif
  26.  
  27. #include <intuition/classes.h>
  28.  
  29. #include <graphics/gfxmacros.h>
  30.  
  31. #define D(x)    ;
  32. #define DI(x)    x
  33.  
  34. struct Frame1Data {
  35.     /* right now, this is kept in pixels, and isn't adjusted
  36.      * for resolution.  A fancier version might take this
  37.      * parameter in "resolution ticks"
  38.      */
  39.     UWORD        f1d_LineWidth;
  40. };
  41.  
  42. #define IM(o)    ((struct Image *)(o))    /* transparent base class */
  43.  
  44. #define DEFAULTLINEWIDTH    1
  45.  
  46. /* public class    */
  47. #define PRIVATECLASS    FALSE
  48.  
  49. #if PRIVATECLASS
  50. #define MYCLASSID    (NULL)
  51. #else
  52. #define MYCLASSID    "frame1class"
  53. #endif
  54. extern struct Library    *IntuitionBase;
  55.  
  56. #define SUPERCLASSID    (IMAGECLASS)
  57.  
  58. Class    *
  59. initFrame1Class()
  60. {
  61.     ULONG __saveds    dispatchFrame1();
  62.     ULONG    hookEntry();
  63.     Class    *cl;
  64.     Class    *MakeClass();
  65.  
  66.     DI( printf("init Frame1Class\n"));
  67.  
  68.     if ( cl =  MakeClass( MYCLASSID, 
  69.         SUPERCLASSID, NULL,        /* superclass is public      */
  70.          sizeof (struct Frame1Data),    /* my object's instance data */
  71.         0) )
  72.     {
  73.     /* initialize the cl_Dispatcher Hook    */
  74.     DI( printf("class at %lx\n", cl ));
  75.     cl->cl_Dispatcher.h_Entry = hookEntry;
  76.     cl->cl_Dispatcher.h_SubEntry = dispatchFrame1;
  77.     cl->cl_Dispatcher.h_Data = (VOID *) 0xFACE;    /* unused */
  78.  
  79. #if !PRIVATECLASS
  80.     AddClass( cl );            /* make public and available    */
  81. #endif
  82.     }
  83.     return ( cl );
  84. }
  85.  
  86. freeFrame1Class( cl )
  87. Class    *cl;
  88. {
  89.     return ( FreeClass( cl )  );
  90. }
  91.  
  92. ULONG __saveds 
  93. dispatchFrame1( cl, o, msg )
  94. Class   *cl;
  95. Object  *o;
  96. Msg     msg;
  97. {
  98.     Object          *newobj;
  99.     struct Frame1Data     *f1d;
  100.  
  101.     switch ( msg->MethodID )
  102.     {
  103.     case OM_NEW:
  104.     /* let superclass do it's creation routine first    */
  105.     if ( newobj = (Object *) DSM( cl, o, msg ) )
  106.     {
  107.         /* init my instance data    */
  108.  
  109.         /* get pointer to it, like a good fellow    */
  110.         f1d = INST_DATA( cl, newobj );
  111.  
  112.         /* mandatory default init */
  113.         f1d->f1d_LineWidth = DEFAULTLINEWIDTH;
  114.  
  115.         /* may override f1d_LineWidth    */
  116.         setFrame1Attrs( cl, newobj, msg );
  117.     }
  118.  
  119.     return ( (ULONG) newobj );
  120.  
  121.     case OM_GET:
  122.     return ( (ULONG) getFrame1Attrs( cl, o, msg  ) );
  123.  
  124.     case OM_SET:
  125.     DSM( cl, o, msg );        /* let the superclass see the atts */
  126.     setFrame1Attrs( cl, o, msg  );    /* set the ones I care about       */
  127.     return ( (ULONG) 1 );        /* i'm happy               */
  128.  
  129.     case IM_DRAW:            /* draw with state */
  130.     case IM_DRAWFRAME:            /* special case of draw    */
  131.     return ( (ULONG) drawFrame1( cl, o, msg ) );
  132.  
  133.     case IM_FRAMEBOX:
  134.     frameBox( cl, o, msg );
  135.         return ( 1 );            /* let him know I support this    */
  136.  
  137.     /* use superclass defaults */
  138.     case IM_HITFRAME:
  139.     case IM_ERASEFRAME:
  140.  
  141.     case IM_HITTEST:
  142.     case IM_ERASE:
  143.     case OM_DISPOSE:
  144.     default:
  145.     return ( (ULONG) DSM( cl, o, msg ) );
  146.     }
  147. }
  148.  
  149. /*
  150.  * return surrounding box, with a little bit of space.
  151.  * If caller wants more space, he can pass me a larger
  152.  * box
  153.  */
  154. frameBox( cl, o, msg )
  155. Class        *cl;
  156. Object        *o;
  157. struct impFrameBox    *msg;    /* superset of impDraw    */
  158. {
  159.     struct Frame1Data *f1d;
  160.     UWORD        surround_room;
  161.     struct IBox    *fbox;
  162.  
  163.     f1d = INST_DATA( cl, o );
  164.  
  165.     fbox = msg->imp_FrameBox;
  166.  
  167.     D( printf("frameBox height %lx\n", msg->imp_FrameBox->Height ) );
  168.  
  169.     if ( ! ( msg->imp_FrameFlags & FRAMEF_SPECIFY ) )
  170.     {
  171.         *fbox = *msg->imp_ContentsBox;
  172.         surround_room = (f1d->f1d_LineWidth << 1);
  173.         fbox->Width += (surround_room << 1);
  174.         fbox->Height += (surround_room << 1);
  175.  
  176.         fbox->Left -= surround_room;
  177.         fbox->Top  -= surround_room;
  178.  
  179.         D( kprintf("frame cont. height %ld query height %ld\n",
  180.             msg->imp_ContentsBox->Height, fbox->Height ) );
  181.     }
  182.     else
  183.     {
  184.         /* use given dimensions and center    */
  185.         fbox->Left =  msg->imp_ContentsBox->Left -
  186.         (fbox->Width - msg->imp_ContentsBox->Width )/2;
  187.         fbox->Top =  msg->imp_ContentsBox->Top - 
  188.         (fbox->Height - msg->imp_ContentsBox->Height )/2;
  189.     }
  190. }
  191.  
  192. drawFrame1( cl, o, msg )
  193. Class        *cl;
  194. Object        *o;
  195. struct impDraw    *msg;    /* superset of impDraw    */
  196. {
  197.     struct Frame1Data     *f1d = INST_DATA( cl, o );
  198.     struct IBox        box;
  199.  
  200.     UWORD        *pens;        /* pen spec array */
  201.     UWORD        ulpen;        /* upper left    */
  202.     UWORD        lrpen;        /* lower right    */
  203.     UWORD        fillpen;    /* filled area    */
  204.  
  205.     /* let's be sure that we were passed a DrawInfo    */
  206.     pens =  ( msg->imp_DrInfo )?  msg->imp_DrInfo->dri_Pens: NULL;
  207.  
  208.     box = *IM_BOX( IM(o) );        /* get Image.Left/Top/Width/Height */
  209.     box.Left += msg->imp_Offset.X;
  210.     box.Top += msg->imp_Offset.Y;
  211.  
  212.     if ( msg->MethodID == IM_DRAWFRAME )
  213.     {
  214.     box.Width = msg->imp_Dimensions.Width;
  215.     box.Height = msg->imp_Dimensions.Height;
  216.     }
  217.  
  218.     switch ( msg->imp_State )
  219.     {
  220.     case IDS_SELECTED:
  221.     case IDS_INACTIVESELECTED:
  222.     ulpen = pens? pens[ shadowPen ]: 2;
  223.     lrpen = pens? pens[ shinePen ]: 1;
  224.     fillpen = pens? pens[ hifillPen ]: 3;
  225.     break;
  226.  
  227.     case IDS_NORMAL:    /* doesn't use activefill in borders now */
  228.     case IDS_DISABLED:    /* I don't have a ghosted version yet     */
  229.     case IDS_INACTIVENORMAL:    /* doesn't use activefill in borders now */
  230.     default:
  231.     ulpen = pens? pens[ shinePen ]: 2;
  232.     lrpen = pens? pens[ shadowPen ]: 1;
  233.     fillpen = pens? pens[ backgroundPen ]: 0;
  234.     break;
  235.     }
  236.  
  237.     embossedBoxTrim( msg->imp_RPort, &box,
  238.     f1d->f1d_LineWidth, f1d->f1d_LineWidth,
  239.     ulpen, lrpen );
  240.  
  241.     /* interior */
  242.     interiorBox( msg->imp_RPort, &box,
  243.     f1d->f1d_LineWidth,    /* inset in x dim */
  244.     f1d->f1d_LineWidth,    /* inset in y dim */
  245.     fillpen );
  246. }
  247.  
  248. /* return requested attribute value    */
  249. getFrame1Attrs( cl, o, msg )
  250. Class        *cl;
  251. Object        *o;
  252. struct opGet    *msg;
  253. {
  254.     struct Frame1Data     *f1d = INST_DATA( cl, o );
  255.  
  256.     if ( msg->opg_AttrID == IA_LINEWIDTH )
  257.     {
  258.         *msg->opg_Storage = f1d->f1d_LineWidth;
  259.     return ( 1 );
  260.     }
  261.     else
  262.         return ( DSM( cl, o, msg ) );
  263.  
  264. }
  265.  
  266. /* set specified attribute value.
  267.  * Technique provided is a little more general than we need ...
  268.  */
  269. setFrame1Attrs( cl, o, msg )
  270. Class        *cl;
  271. Object        *o;
  272. struct opSet    *msg;
  273. {
  274.     struct TagItem    *NextTagItem();
  275.     struct TagItem    *tags = msg->ops_AttrList;
  276.     struct TagItem    *tag;
  277.     ULONG        tidata;
  278.  
  279.     struct Frame1Data     *f1d = INST_DATA( cl, o );
  280.  
  281.     while ( tag = NextTagItem( &tags ) )
  282.     {
  283.     tidata = tag->ti_Data;
  284.     switch ( tag->ti_Tag )
  285.     {
  286.     case IA_LINEWIDTH:
  287.         f1d->f1d_LineWidth = tidata;
  288.         break;
  289.     }
  290.     }
  291. }
  292.  
  293. /* fill region centered in a box */
  294. interiorBox( rp, b, xw, yw, pen )
  295. struct RastPort    *rp;
  296. struct IBox    *b;
  297. {
  298.     if ( (b->Width > (xw<<1)) && (b->Height > (yw<<1)) )
  299.     {
  300.     rp->Mask = -1;
  301.     BNDRYOFF( rp );
  302.     SetAfPt(rp, NULL, 0);
  303.     SetDrMd(rp, JAM2);
  304.     SetAPen(rp, pen);
  305.     RectFill( rp,
  306.         b->Left + xw,
  307.         b->Top + yw,
  308.         b->Left + b->Width - 1 - xw,
  309.         b->Top + b->Height - 1 - yw );
  310.     }
  311. }
  312.  
  313. /* suggestion of Talin: don't draw upper-right and lower-left points */
  314. /* ignoring thickness for now    */
  315. embossedBoxTrim( rp, b, hthick, vthick, ulpen, lrpen )
  316. struct RastPort    *rp;
  317. struct IBox    *b;
  318. {
  319.     int    bottom, right;
  320.  
  321.     bottom = b->Top + b->Height - 1;
  322.     right = b->Left + b->Width - 1;
  323.  
  324.     /* upper right edges    */
  325.     SetAPen( rp, ulpen );
  326.  
  327.     Move( rp, b->Left, bottom - 1 );
  328.     Draw( rp, b->Left, b->Top );
  329.     Draw( rp, right - 1, b->Top );
  330.  
  331.     /* lower right edges    */
  332.     SetAPen( rp, lrpen );
  333.  
  334.     Move( rp, right, b->Top + 1 );
  335.     Draw( rp, right, bottom );
  336.     Draw( rp, b->Left + 1, bottom );
  337. }
  338.  
  339.